import { Component, EventEmitter, HostBinding, Input, OnInit, Output, TemplateRef, ViewChild } from '@angular/core';
import { NotifyService } from '@farris/ui-notify';
import { TreeNode, TreeTableComponent } from '@farris/ui-treetable';
import { IdService } from '@farris/ui-common';
import { DesignViewModelService, DomService, FormBasicService, FormBindingType } from '@farris/designer-services';
import { ControlService } from '../../../../../../service/control.service';
import { DgControl } from '../../../../../../utils/dg-control';
import { FieldTreeBuilder, FieldTreeNode } from '@farris/designer-devkit';

@Component({
  selector: 'app-create-field-set',
  templateUrl: './create-field-set.component.html',
  styleUrls: ['./create-field-set.component.css']
})
export class CreateFieldSetComponent implements OnInit {
  @Input() componentId: string;

  @Input() schemaDOMMapping: any;
  @Output() closeModal = new EventEmitter<any>();
  @Output() submitModal = new EventEmitter<any>();

  @ViewChild('footer') modalFooter: TemplateRef<any>;
  @ViewChild('bindFieldColTpl') bindFieldColTpl: TemplateRef<any>;

  @HostBinding('class')
  class = 'd-flex h-100 py-2 px-3';


  /** 卡片组件节点 */
  componentNode: any;

  /** 卡片组件内的Form节点 */
  compFormNode: any;

  // 树表数据
  treeData: TreeNode[] = [];

  // 树表列配置
  treeCols = [];

  // 树表实例
  @ViewChild('treeTable') treeTable: TreeTableComponent;

  /** 分组标题 */
  fieldSetTitle: string;

  /** 选中的行数据 */
  checkeds: FieldTreeNode[] = [];

  constructor(
    private domService: DomService,
    private notifyService: NotifyService,
    private dgVMService: DesignViewModelService,
    private formBasicService: FormBasicService,
    private controlService: ControlService,
    private idService: IdService) { }


  ngOnInit() {
    this.componentNode = this.domService.getComponentById(this.componentId);

    // 收集当前组件下的控件，并剔除分组下的控件、没有绑定信息的控件、绑定的字段被移除的控件
    this.treeData = this.buildFieldTreeData(this.componentNode.viewModel);
    this.treeData = this.treeData.filter((treeNode: any) => !treeNode.isGroupNode && !treeNode.isNoBinding && !treeNode.isRemoved);

    this.compFormNode = this.domService.selectNode(this.componentNode, item => item.type === DgControl.Form.type);


    this.treeCols = [
      { field: 'name', title: '名称' },
      { field: 'bindingPath', title: '绑定字段', template: this.bindFieldColTpl }];
  }


  buildFieldTreeData(viewModelId: string) {
    const fieldTreeBuilder = new FieldTreeBuilder(this.schemaDOMMapping, this.dgVMService, this.domService, this.formBasicService);

    const treeData = fieldTreeBuilder.buildFieldTreeData(viewModelId);
    return treeData;
  }

  clickCancel() {
    this.closeModal.emit();
  }

  clickConfirm() {

    if (!this.fieldSetTitle) {
      this.notifyService.warning('请填写分组标题');
      return;
    }
    this.checkeds = this.treeTable.checkeds as FieldTreeNode[];
    if (!this.checkeds || this.checkeds.length === 0) {
      this.notifyService.warning('请选择字段');
      return false;
    }

    const selectedControls = this.checkeds.map(c => c.control);

    const groupId = this.idService.generate();

    this.changeViewModelFields(groupId);
    this.changeFormElement(groupId);

    this.submitModal.emit();
  }


  /**
   * 字段搜索
   */
  searchField($event) {
    if ($event) {
      const { field, value } = $event;
      this.treeTable.searchHandle.search(field, value);
    } else {
      this.treeTable.searchHandle.search('*', '');
    }

  }

  private changeViewModelFields(groupId: string) {
    this.checkeds.forEach((check: FieldTreeNode) => {
      const dgChangeSet = {
        groupId,
        groupName: this.fieldSetTitle
      };
      if (check.isBindVariable) {
        this.changeVMGroupForVariableBinding(check.data, dgChangeSet);
      } else {
        const dgViewModel = this.dgVMService.getDgViewModel(this.componentNode.viewModel);

        dgViewModel.changeField(check.data.id, dgChangeSet);
      }
    });
  }

  /**
   * 绑定变量的控件 修改VM中的分组信息
   */
  private changeVMGroupForVariableBinding(data: any, changeSet: { groupId: string, groupName: string }) {
    const viewModel = this.domService.getViewModelById(this.componentNode.viewModel);
    const field = viewModel.fields.find(f => f.id === data.id);
    if (field) {
      Object.assign(field, changeSet);
    } else {
      viewModel.fields.push({
        type: FormBindingType.Variable,
        id: data.id,
        fieldName: data.code,
        groupId: changeSet.groupId || '',
        groupName: changeSet.groupName || '',
      });
    }
  }

  private changeFormElement(groupId: string) {
    // 1、创建分组控件
    const fieldSetMetadata = this.controlService.getControlMetaData(DgControl.FieldSet.type);
    fieldSetMetadata.id = groupId;
    fieldSetMetadata.title = this.fieldSetTitle;
    fieldSetMetadata.appearance = { class: 'col-12 px-0' };

    // 2、将选中的输入控件移动至分组控件
    const movedControls = this.checkeds.map(c => c.control);

    fieldSetMetadata.contents = movedControls;

    const movedControlIds = movedControls.map(c => c.id);
    const formNode = this.domService.selectNode(this.componentNode, item => item.type === DgControl.Form.type);
    formNode.contents = formNode.contents.filter(c => !movedControlIds.includes(c.id));

    // 3、将分组控件添加到Form中
    formNode.contents.push(fieldSetMetadata);


  }
}
